Skip to content

Dev - #5

Open
recepteksi wants to merge 40 commits into
mainfrom
dev
Open

Dev#5
recepteksi wants to merge 40 commits into
mainfrom
dev

Conversation

@recepteksi

Copy link
Copy Markdown
Owner

No description provided.

recepteksi and others added 30 commits April 6, 2026 12:23
Problem 1: Objects couldn't be dropped everywhere during drag
- Root cause: ARCore hit test only updates position on valid plane surfaces
- Fix: Keep last valid position when hit test fails, object stays in place
- Added lastValidDragPosition to track successful drag positions

Problem 2: Trash zone deletion not working reliably
- Root cause: onDragUpdate only called when currentObj found in placedObjects
- Fix: Always call onDragUpdate even if object not found (use default position)
- Added final trash zone check in onDragEnd to ensure deletion works

Fixes: fix-drag-drop-position, fix-trash-zone-delete
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added isOverTrashZone() helper function that checks both X (right side) and Y (bottom) coordinates
- Fixed trash zone hit detection to properly detect when object is dragged to bottom-right corner
- Updated onDragMove and onDragEnd to use the new isOverTrashZone() function
- Constants: TRASH_ZONE_SIZE_DP=80, TRASH_ZONE_MARGIN_DP=16

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fixed magic strings in TrashZone (now uses localized strings)
- Removed unused 'progress' variable
- Added release_to_delete and drag_to_delete strings (EN and TR)
- Improved drag movement with camera ray projection fallback
  - Objects can now be moved to areas without detected planes
  - Uses camera's view matrix to project movement

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: Camera ray projection fallback was using absolute screen
coordinates instead of delta movement, causing erratic object positioning.

Solution:
- Track last screen position (dragLastScreenX/Y) for delta calculation
- Use screen delta movement instead of absolute normalized coordinates
- Project finger movement to world XZ plane using camera vectors
- Apply delta to current position instead of recalculating from scratch
- Scale pixel-to-world conversion based on object distance from camera

Also includes style improvements to TrashZone:
- Add semi-transparent background
- Add subtle shadow effect
- Add subtle border
- Center text properly
- Increase size for better text fit

Fixes: drag-everywhere-bug
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add semi-transparent background (alpha 0.7 normal, 0.85 hovered)
- Add subtle shadow effect for better visibility
- Add subtle border for definition
- Center text with TextAlign.Center and fillMaxWidth
- Increase size to 100x90dp for better text fit
- Add fillMaxSize to Column for proper centering

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: isOverTrashZone() was using incorrect dimensions (80dp x 80dp)
that didn't match the actual TrashZone component (100dp x 90dp).

Solution: Updated trash zone detection to use the correct dimensions:
- trashZoneWidth = 100.dp (matches component's width)
- trashZoneHeight = 90.dp (matches component's height)
- trashZonePadding = 16.dp

The detection area now correctly matches the visual trash zone position,
enabling reliable drag-to-delete functionality.

Fixes: trash-zone-delete-bug
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added ObjectThumbnail composable for displaying 3D object previews
- Updated ObjectListItem in ARScreen with thumbnail support
- Updated ObjectListItem in ObjectListScreen with thumbnail support
- Uses placeholder icon (ViewInAr) based on model type
- Thumbnails display in styled boxes with rounded corners
- Selected state shows highlighted background

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added Koin dependencies (koin-core, koin-android, koin-compose)
- Created DI modules: dataModule, applicationModule, presentationModule
- Created platform-specific modules for Android and iOS data sources
- Updated MainActivity to initialize Koin
- Updated App.kt to use koinInject() for ViewModels
- Simplified dependency wiring through DI container

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added CapturedPhoto model in domain layer
- Created MediaRepository interface
- Implemented CapturePhotoUseCase
- Added Android MediaRepositoryImpl with MediaStore API
- Added capture button to AR screen (camera icon)
- Implemented PixelCopy-based AR view capture
- Integrated with Koin DI
- Added iOS placeholder implementation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add CapturedVideo domain model to CapturedMedia.kt
- Extend MediaRepository interface with video recording methods
- Create RecordVideoUseCase for recording state management
- Update Android MediaRepositoryImpl with video recording support
- Add RecordingState sealed class to ARViewModel
- Add startRecording/stopRecording/toggleRecording functions
- Update ARScreen with VideoRecordButton and RecordingIndicator
- Add iOS MediaRepositoryIOSImpl stub implementation
- Update DI modules with RecordVideoUseCase
- Fix GalleryViewModel coroutine scope issue
- Fix iOS MainViewController to use Koin injection

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added ObjectGalleryScreen with grid layout (2-column LazyVerticalGrid)
- Created ObjectGalleryCard component with visual previews
- Implemented model type badges (GLB/GLTF/USDZ/OBJ)
- Added search/filter functionality for objects
- Added empty state with import CTA
- Added no-results state for search
- Updated App.kt navigation with Screen.ObjectGallery
- Added i18n strings (EN/TR) for gallery

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added Kover plugin for test coverage reporting
- Configured HTML and XML report generation
- Added exclusion filters for generated code
- Reports generated at build/reports/kover/

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add VideoRecorder class for ARSceneView video capture using MediaRecorder
- Add camera-style controls: CameraStyleRecordButton, RecordingTimerDisplay
- Add CameraControlsBar with photo, record, and gallery buttons
- Add RecordingBorderGlow effect during recording
- Add recording duration timer in ARViewModel
- Update ARScreen with new camera-style controls layout
- Connect VideoRecorder to MediaRepository via callbacks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
UI Changes:
- Move selected object indicator from bottom to top-left
- Redesign camera controls bar with clean centered layout
- Add semi-transparent background to camera controls
- Fix overlapping elements in AR screen

Video Recording Fix:
- Connect VideoRecorder directly to MediaRepository via Koin
- Register recording callbacks when ARSceneView is ready
- Clear callbacks properly on dispose

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add ModelPreviewThumbnail expect/actual for cross-platform support
- Android: SceneView-based 3D rendering with auto-rotation
- iOS: Placeholder icon fallback
- Integrate into ObjectGalleryScreen
- Handle loading states and errors gracefully

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove environmentLoader to avoid missing HDR file crash
- Simplify Scene setup to use default environment
- Improve error handling in model loading

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
3D SceneView preview causing stability issues.
Temporarily disabled until resolved.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rewrite VideoRecorder with MediaCodec + MediaMuxer approach
- Add thread safety with CountDownLatch synchronization
- Register GalleryViewModel in Koin AppModule
- Add gallery use case registrations (GetPhotos, GetVideos, DeletePhoto, DeleteVideo)
- Fix GalleryScreen callbacks in App.kt navigation
- Add MediaItem import for gallery functionality
- Fix capturePhoto → requestCapture method call

Video recording now properly:
- Handles cross-thread calls from IO dispatcher
- Uses InputSurface from MediaCodec instead of Canvas drawing
- Caps resolution at 1920x1080 with aspect ratio preservation
- Uses 8 Mbps bitrate for efficient encoding

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: startKoin was called unconditionally in onCreate,
causing KoinApplicationAlreadyStartedException when Activity
recreates (e.g., on configuration change, back navigation).

Solution: Check GlobalContext.getOrNull() before initializing
Koin to skip initialization if already started.

Fixes: KAN-1
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ARViewModel was not receiving CapturePhotoUseCase due to positional
parameter injection. Changed to named parameter injection to ensure
proper dependency resolution.

Fixes: KAN-4

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace SpaceEvenly layout with weighted sections
- Use Box with weight(1f) for left and right sections
- Center record button uses fixed size (80dp) without weight
- Gallery button aligned to end of left section
- Photo capture button aligned to start of right section
- Remove unused placeholder boxes
- Clean up unused imports

Fixes: KAN-7

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: GalleryViewModel was being eagerly injected at App()
composition time, causing loadMedia() to run immediately even
before user navigates to Gallery screen. This triggered premature
MediaRepository access.

Solution: Move GalleryViewModel injection inside the Screen.Gallery
when branch, so it only initializes when user actually navigates
to the Gallery screen.

Fixes: KAN-6
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Android: Fix SceneView crash with 3 root causes resolved:
- Remove Dispatchers.IO dispatch (Filament must finalize on main thread)
- Add key(modelPath) to prevent EGL context exhaustion in LazyGrid
- Add DisposableEffect for deterministic GPU resource cleanup

iOS: Implement platform-native preview:
- USDZ: SCNView (SceneKit) via UIKitView with SCNAction auto-rotation
- GLB/GLTF: QLThumbnailGenerator (QuickLook) async thumbnail
- Fallback: placeholder icon for unsupported formats

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract pure logic into ModelPreviewThumbnailHelper for testability:
- resolvePreviewStrategy: iOS extension routing (usdz/glb/placeholder)
- resolveInitialAndroidState: file existence guard
- resolveAndroidStateAfterLoad: post-load state machine
- extractExtension: shared path utility

27 tests with Given-When-Then pattern using kotlin.test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
C-1: Wire ModelPreviewThumbnailHelper into actual implementations
- Android: resolveInitialAndroidState() + resolveAndroidStateAfterLoad()
- iOS: resolvePreviewStrategy() replaces inline when block

C-2: Guard GLBThumbnailPreview against use-after-dispose
- DisposableEffect nulls imageViewRef on disposal

M-1: Replace 8 wildcard imports with explicit symbols in iOS file

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: rememberEngine() created a new Filament Engine per thumbnail
composable in LazyVerticalGrid. Filament has a hard limit of ~1 engine
instances; creating one per visible grid cell caused immediate native crash.

Fix: Introduce ModelPreviewEngineProvider with singleton Engine pattern:
- commonMain: expect interface with lifecycle-aware engine sharing
- androidMain: activity-scoped Engine singleton via rememberUpdatedState
- iosMain: no-op (SceneView not used; SCNView manages its own context)

ObjectGalleryScreen updated to provide engine via CompositionLocal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
recepteksi and others added 8 commits April 8, 2026 20:03
- Add linkerOpts("-framework", "SceneKit") in build.gradle.kts
- Remove QLThumbnailGenerator usage (not available in Kotlin/Native cinterop)
- GLB format falls back to placeholder on iOS (primary iOS format is USDZ)
- Fix explicit Icon import replacing fully-qualified call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove orphaned linkerOpts("-framework", "QuickLook") — QuickLook
  is no longer used after QLThumbnailGenerator removal
- Update stale KDoc for PreviewStrategy.GLB_THUMBNAIL to reflect
  placeholder behaviour instead of QLThumbnailGenerator

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add explicit engine.destroy() + modelLoader.destroy() in DisposableEffect
  to prevent Filament GL resource leaks on repeated gallery open/close
- Narrow ModelPreviewEngineProvider scope to wrap only ObjectGalleryGrid
  instead of the entire screen (dialogs/snackbars no longer inside provider)
- Make ObjectGalleryCard private (only used within ObjectGalleryScreen)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rag-delete

- Remove explicit arSceneView?.destroy() in DisposableEffect — SceneView's
  onDetachedFromWindow already destroys; double-destroy caused NPE in CameraNode
- Revert worldToScreen to require TrackingState.TRACKING — relaxed check caused
  false positive node hits that blocked model placement
- Guard onFrame animation loop with isAttachedToWindow to prevent NPE on destroy
- Add PhotoThumbnail expect/actual for persistent URI-based thumbnail display
- Load last captured photo path from GetPhotosUseCase on startup for persistence
- Fix GalleryScreen LazyVerticalGrid duplicate key crash (photo vs video IDs collide)
- Hide CameraControlsBar during drag so trash zone receives touch events
- Add GLB animation playback via onFrame + Filament Animator API
- Fix GalleryViewModel scope (factory → single) to prevent multiple VM instances

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Gallery crash: remove double-destroy in DisposableEffect (NPE in CameraNode)
- Model placement regression: restore TrackingState.TRACKING check in worldToScreen
- Thumbnail persistence: URI-based PhotoThumbnail loaded from GetPhotosUseCase on startup
- Animated GLB models: drive Filament Animator via onFrame callback
- Drag-to-delete: hide CameraControlsBar during drag so trash zone gets touch events
- GalleryScreen crash: prefix photo/video keys in LazyVerticalGrid to avoid duplicate keys
@recepteksi
recepteksi force-pushed the dev branch 2 times, most recently from b640132 to 26eba64 Compare April 17, 2026 18:54
recepteksi and others added 2 commits April 18, 2026 00:02
Changed `if (bitmap != null) { Image(bitmap = bitmap!!) }` to
`bitmap?.let { Image(bitmap = it, ...) }` to prevent NPE from force-unwrap.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…handling

- Handle content:// URI inputStream returning null explicitly
- Handle file:// prefix stripping for absolute paths
- Add file existence check before decodeFile
- Catch IllegalArgumentException for malformed images
- Catch SecurityException for permission issues
- Add comprehensive logging for debugging

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant